import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import com.alibaba.fastjson.*;

/**
 * 可以实现和客户端的相互发送消息的交互 可以是多台电脑
 * */

public class Server extends Thread {
    private int portz;
    // 用来存放连接上的用户的socket对象的值
    List<Socket> list = new ArrayList<>();

    // 定义服务器接口ServerSocket
    ServerSocket server = null;

    // 定义一个服务器，定义端口
    public Server(int port) {
        System.out.println("启动服务器");
        portz=port;
        try {
            server = new ServerSocket(port);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 发送消息的线程
    @Override
    public void run() {
        super.run();
        DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {

            while (true) {
                // 建立socket接口，accept方法是一个阻塞进程,等到有用户连接才往下走
                // 定义Socket类
                System.out.println("监听端口："+portz);
                Socket socket = server.accept();
                // 在服务器显示连接的上的电脑、
                String message = socket.getInetAddress().getHostAddress().toString();
                System.out.println(dateFormat.format(new Date())+"=>"+message+"连接上了");

                //验证是否是客户端登录
                int len = 0;
                byte[] buf = new byte[1024];
                len = socket.getInputStream().read(buf);
                String check=new String(buf, 0, len,"UTF-8");
                System.out.println(check);
                if (!"TalkingRoom".equals(check)){
                    socket.getOutputStream().write(new String("禁止非法连接！").getBytes("UTF-8"));
                    socket.close();
                }else {
                    // 把连接上的用户添加到集合；里面去
                    list.add(socket);
                    //开始新连接用户的线程，用于该可以一直读取数据
                    new readerThread(socket).start();;
                }
                // 向用户发送消息
//                int len1 = 0;
//                byte[] buf1 = new byte[1024];
//                len1 = socket.getInputStream().read(buf);
//                String name=new String(buf1, 0, len1,"UTF-8");
//                Message sys=new Message();
//                sys.setName("系统");
//                sys.setMsg("<strong>"+name+"</strong> 加入房间");
//                sys.setDate(new Date());
//                System.out.println(JSONObject.toJSONString(sys));
//                SendMessageToAllUser(JSONObject.toJSONString(sys));
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 把消息发送给每一个用户，涉及到写的操作OutStream
    private void SendMessageToAllUser(String message) {
        // 拿到每一个用户的socket对象，对其进行写入数据
        for (Socket socket : list) {
            // 判读之前保存的连接是否还在
            if (socket != null && socket.isConnected()) {
                try {
                    OutputStream os = socket.getOutputStream();
                    os.write(message.getBytes("UTF-8"));
                    os.flush();// 刷新一下写入的数据，很有必要
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 读取客户端的信息
    class readerThread extends Thread {
        InputStream is = null;
        Socket ss;

        // 这里传入一个socket对象，因为每一个用户都要用一个不同的线程存放的socket对象来进行一直读取数据
        public readerThread(Socket socket) {
            ss=socket;
            try {
                // 获取输入流
                is = socket.getInputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void run() {
            DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            super.run();
            try {
                int len = 0;
                byte[] buf = new byte[1024];
                while ((len = is.read(buf)) != -1) {
                    // 把读取到的数据发送给其他用户
                    System.out.println(new String(buf, 0, len,"UTF-8"));
                    SendMessageToAllUser(new String(buf, 0, len,"UTF-8"));
                }
            } catch (IOException e) {
                try {
                    if ("Connection reset".equals(e.getMessage())){
                        System.out.println(dateFormat.format(new Date())+"=>"+ss.getInetAddress()+":"+ss.getPort()+" 断开连接");
                        ss.getInputStream().close();
                        ss.close();
                        list.remove(ss);
                    }
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
//                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
//这里服务器只需要定义一个端口号就可以了，IP地址程序会自动获取
//但是客户端需要连接这个服务器时，需要知道它的IP地址还有端口号
//ip地址的查看方法：进入cmd窗口，输入ipconfig/all可以看到
        Server server=new Server(8888);
        server.start();
    }
}